#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
建造者模式 (Builder Pattern) - Python实现详解

概述引导：
建造者模式用于构建复杂对象，将构建过程与表示分离。
对于Java工程师来说，Python的建造者模式更加灵活和简洁。

学习要点：
1. Python的方法链式调用实现
2. 使用dataclass简化产品类
3. 抽象基类的使用
4. 流式接口设计

Java对比要点：
- Java需要大量getter/setter，Python可用属性装饰器
- Java的接口实现更严格，Python使用ABC更灵活
- Python支持默认参数，减少重载方法
- Python的字符串格式化更简洁

关键理解：
建造者模式在Python中可以更优雅地实现，特别是结合dataclass和方法链。
"""

from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from typing import Optional, List
from enum import Enum


class CarType(Enum):
    """汽车类型枚举 - Java中通常用enum实现"""
    SEDAN = "轿车"
    SUV = "SUV"
    SPORTS = "跑车"
    TRUCK = "卡车"


class Engine:
    """引擎类 - 展示组合关系"""
    def __init__(self, power: int, fuel_type: str):
        self.power = power  # 马力
        self.fuel_type = fuel_type  # 燃料类型
    
    def __str__(self):
        return f"{self.power}马力{self.fuel_type}引擎"


@dataclass
class Car:
    """
    汽车产品类 - 使用dataclass简化
    
    Java对比：
    - Java需要写大量getter/setter方法
    - Python的dataclass自动生成__init__, __repr__等方法
    - Python的类型提示更简洁
    """
    car_type: CarType = CarType.SEDAN
    engine: Optional[Engine] = None
    seats: int = 5
    color: str = "白色"
    features: List[str] = field(default_factory=list)
    price: float = 0.0
    
    def __str__(self):
        features_str = ", ".join(self.features) if self.features else "无特殊配置"
        return f"""
汽车信息：
- 类型: {self.car_type.value}
- 引擎: {self.engine or "未配置"}
- 座位数: {self.seats}
- 颜色: {self.color}
- 特殊配置: {features_str}
- 价格: ¥{self.price:,.2f}
        """.strip()


class CarBuilder(ABC):
    """
    抽象建造者接口
    
    Java对比：
    - Java使用interface或abstract class
    - Python的ABC提供更灵活的抽象机制
    - Python可以混合抽象方法和具体方法
    """
    
    def __init__(self):
        self.reset()
    
    def reset(self):
        """重置建造者状态"""
        self._car = Car()
    
    @abstractmethod
    def set_car_type(self, car_type: CarType) -> 'CarBuilder':
        """设置汽车类型 - 返回self支持链式调用"""
        pass
    
    @abstractmethod
    def set_engine(self, power: int, fuel_type: str) -> 'CarBuilder':
        """设置引擎"""
        pass
    
    @abstractmethod
    def set_seats(self, seats: int) -> 'CarBuilder':
        """设置座位数"""
        pass
    
    @abstractmethod
    def set_color(self, color: str) -> 'CarBuilder':
        """设置颜色"""
        pass
    
    @abstractmethod
    def add_feature(self, feature: str) -> 'CarBuilder':
        """添加特殊配置"""
        pass
    
    @abstractmethod
    def set_price(self, price: float) -> 'CarBuilder':
        """设置价格"""
        pass
    
    def get_result(self) -> Car:
        """获取构建结果"""
        result = self._car
        self.reset()  # 重置以便下次使用
        return result


class ConcreteCarBuilder(CarBuilder):
    """
    具体建造者实现
    
    Python优势：
    - 方法链式调用更自然
    - 类型提示提供更好的IDE支持
    - 无需显式实现接口声明
    """
    
    def set_car_type(self, car_type: CarType) -> 'ConcreteCarBuilder':
        """设置汽车类型"""
        self._car.car_type = car_type
        return self  # 返回self支持链式调用
    
    def set_engine(self, power: int, fuel_type: str) -> 'ConcreteCarBuilder':
        """设置引擎"""
        self._car.engine = Engine(power, fuel_type)
        return self
    
    def set_seats(self, seats: int) -> 'ConcreteCarBuilder':
        """设置座位数"""
        if seats < 2 or seats > 8:
            raise ValueError("座位数必须在2-8之间")
        self._car.seats = seats
        return self
    
    def set_color(self, color: str) -> 'ConcreteCarBuilder':
        """设置颜色"""
        self._car.color = color
        return self
    
    def add_feature(self, feature: str) -> 'ConcreteCarBuilder':
        """添加特殊配置"""
        if feature not in self._car.features:
            self._car.features.append(feature)
        return self
    
    def set_price(self, price: float) -> 'ConcreteCarBuilder':
        """设置价格"""
        if price < 0:
            raise ValueError("价格不能为负数")
        self._car.price = price
        return self


class CarDirector:
    """
    指挥者类 - 封装构建过程
    
    Java对比：
    - Java通常需要更多的方法重载
    - Python可以使用默认参数简化接口
    - Python的字符串处理更简洁
    """
    
    def __init__(self, builder: CarBuilder):
        self._builder = builder
    
    def construct_economy_car(self) -> Car:
        """构建经济型轿车"""
        return (self._builder
                .set_car_type(CarType.SEDAN)
                .set_engine(120, "汽油")
                .set_seats(5)
                .set_color("白色")
                .add_feature("空调")
                .add_feature("收音机")
                .set_price(80000)
                .get_result())
    
    def construct_luxury_suv(self) -> Car:
        """构建豪华SUV"""
        return (self._builder
                .set_car_type(CarType.SUV)
                .set_engine(300, "汽油")
                .set_seats(7)
                .set_color("黑色")
                .add_feature("真皮座椅")
                .add_feature("导航系统")
                .add_feature("全景天窗")
                .add_feature("自动驾驶")
                .set_price(500000)
                .get_result())
    
    def construct_sports_car(self) -> Car:
        """构建跑车"""
        return (self._builder
                .set_car_type(CarType.SPORTS)
                .set_engine(500, "汽油")
                .set_seats(2)
                .set_color("红色")
                .add_feature("碳纤维车身")
                .add_feature("运动座椅")
                .add_feature("高性能轮胎")
                .set_price(1000000)
                .get_result())


class FluentCarBuilder:
    """
    流式接口建造者 - Python特色实现
    
    Python优势：
    - 更简洁的实现方式
    - 不需要抽象基类
    - 支持更灵活的配置
    """
    
    def __init__(self):
        self._car = Car()
    
    def type(self, car_type: CarType) -> 'FluentCarBuilder':
        """设置类型 - 简化方法名"""
        self._car.car_type = car_type
        return self
    
    def engine(self, power: int, fuel_type: str = "汽油") -> 'FluentCarBuilder':
        """设置引擎 - 使用默认参数"""
        self._car.engine = Engine(power, fuel_type)
        return self
    
    def seats(self, count: int) -> 'FluentCarBuilder':
        """设置座位数"""
        self._car.seats = count
        return self
    
    def color(self, color: str) -> 'FluentCarBuilder':
        """设置颜色"""
        self._car.color = color
        return self
    
    def features(self, *features: str) -> 'FluentCarBuilder':
        """批量添加特性 - 使用可变参数"""
        self._car.features.extend(features)
        return self
    
    def price(self, amount: float) -> 'FluentCarBuilder':
        """设置价格"""
        self._car.price = amount
        return self
    
    def build(self) -> Car:
        """构建最终产品"""
        result = self._car
        self._car = Car()  # 重置
        return result


def demonstrate_builder_pattern():
    """
    演示建造者模式的使用
    
    概述引导：
    展示建造者模式在Python中的多种实现方式，
    包括传统方式和Python特色的流式接口。
    
    学习要点：
    1. 传统建造者模式的实现
    2. 指挥者模式的使用
    3. 流式接口的设计
    4. 方法链式调用的优势
    
    关键理解：
    建造者模式让复杂对象的构建过程更加清晰和可控。
    """
    print("=== 建造者模式演示 ===")
    print("\n学习目标：")
    print("- 理解建造者模式的构建过程")
    print("- 掌握方法链式调用")
    print("- 学习流式接口设计")
    print("\n重点概念：")
    print("- 复杂对象的分步构建")
    print("- 构建过程与表示分离")
    print("- 相同构建过程创建不同表示")
    print("=" * 50)
    
    # 1. 传统建造者模式
    print("\n1. 传统建造者模式：")
    builder = ConcreteCarBuilder()
    director = CarDirector(builder)
    
    # 构建经济型轿车
    economy_car = director.construct_economy_car()
    print("经济型轿车：")
    print(economy_car)
    
    # 构建豪华SUV
    luxury_suv = director.construct_luxury_suv()
    print("\n豪华SUV：")
    print(luxury_suv)
    
    # 2. 直接使用建造者
    print("\n2. 直接使用建造者（自定义配置）：")
    custom_car = (ConcreteCarBuilder()
                  .set_car_type(CarType.TRUCK)
                  .set_engine(400, "柴油")
                  .set_seats(3)
                  .set_color("蓝色")
                  .add_feature("货箱")
                  .add_feature("四驱系统")
                  .set_price(200000)
                  .get_result())
    print("自定义卡车：")
    print(custom_car)
    
    # 3. 流式接口建造者
    print("\n3. 流式接口建造者：")
    fluent_car = (FluentCarBuilder()
                  .type(CarType.SPORTS)
                  .engine(600, "混合动力")
                  .seats(2)
                  .color("金色")
                  .features("碳纤维车身", "赛车座椅", "涡轮增压")
                  .price(1500000)
                  .build())
    print("流式接口构建的跑车：")
    print(fluent_car)


def demonstrate_java_comparison():
    """
    Java对比演示
    
    Java等价代码：
    ```java
    // Java版本需要更多代码
    public class Car {
        private CarType type;
        private Engine engine;
        private int seats;
        private String color;
        private List<String> features;
        private double price;
        
        // 需要大量getter/setter方法
        public CarType getType() { return type; }
        public void setType(CarType type) { this.type = type; }
        // ... 更多getter/setter
    }
    
    public interface CarBuilder {
        CarBuilder setCarType(CarType type);
        CarBuilder setEngine(int power, String fuelType);
        // ... 更多方法声明
        Car getResult();
    }
    
    public class ConcreteCarBuilder implements CarBuilder {
        private Car car = new Car();
        
        @Override
        public CarBuilder setCarType(CarType type) {
            car.setType(type);
            return this;
        }
        // ... 更多方法实现
    }
    ```
    
    Python优势：
    1. dataclass自动生成样板代码
    2. 类型提示提供更好的开发体验
    3. 方法链更自然
    4. 代码更简洁易读
    """
    print("\n=== Java对比说明 ===")
    print("\nPython优势：")
    print("1. dataclass减少样板代码")
    print("2. 类型提示增强IDE支持")
    print("3. 方法链式调用更自然")
    print("4. 可变参数简化接口")
    print("5. 默认参数减少方法重载")
    
    print("\nJava特点：")
    print("1. 接口实现更严格")
    print("2. 需要大量getter/setter")
    print("3. 类型安全更严格")
    print("4. 编译时检查更全面")


def performance_comparison():
    """
    性能对比测试
    """
    import time
    
    print("\n=== 性能对比 ===")
    
    # 测试传统建造者
    start_time = time.time()
    builder = ConcreteCarBuilder()
    for i in range(1000):
        car = (builder
               .set_car_type(CarType.SEDAN)
               .set_engine(120, "汽油")
               .set_seats(5)
               .set_color("白色")
               .add_feature("空调")
               .set_price(80000)
               .get_result())
    traditional_time = time.time() - start_time
    
    # 测试流式建造者
    start_time = time.time()
    for i in range(1000):
        car = (FluentCarBuilder()
               .type(CarType.SEDAN)
               .engine(120)
               .seats(5)
               .color("白色")
               .features("空调")
               .price(80000)
               .build())
    fluent_time = time.time() - start_time
    
    print(f"传统建造者模式: {traditional_time:.4f}秒")
    print(f"流式接口建造者: {fluent_time:.4f}秒")
    print(f"性能差异: {abs(traditional_time - fluent_time):.4f}秒")


if __name__ == "__main__":
    demonstrate_builder_pattern()
    demonstrate_java_comparison()
    performance_comparison()